{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "d:\\cx\\Anaconda\\envs\\CX\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
            "  from .autonotebook import tqdm as notebook_tqdm\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "pygame 2.6.1 (SDL 2.28.4, Python 3.13.2)\n",
            "Hello from the pygame community. https://www.pygame.org/contribute.html\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "import random\n",
        "import mesa\n",
        "import matplotlib.pyplot as plt\n",
        "from IPython.display import clear_output\n",
        "%matplotlib inline\n",
        "import sys,os,inspect\n",
        "if hasattr(sys.modules[__name__], '__file__'):\n",
        "    _file_name = __file__\n",
        "else:\n",
        "    _file_name = inspect.getfile(inspect.currentframe())\n",
        "CURRENT_FILE_PATH = os.path.dirname(_file_name)\n",
        "sys.path.append(os.getcwd()+\"/../src/\")\n",
        "import Animal\n",
        "import Brain\n",
        "import Game"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Parameters"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [],
      "source": [
        "class parameter():\n",
        "  world_width = 25\n",
        "  world_height = 25\n",
        "\n",
        "  grass_born_size = 1\n",
        "  grass_grow_speed = 0.01\n",
        "  grass_max_size = 10\n",
        "\n",
        "  sheep_born_size = 2\n",
        "  sheep_max_size = 10000\n",
        "  sheep_base_energy_decay = 0.005\n",
        "  sheep_move_energy_cost = 0.02\n",
        "  sheep_eat_speed = 2\n",
        "  sheep_observation_radius = 6\n",
        "  sheep_max_speed = 2\n",
        "\n",
        "  wolf_born_size = 10\n",
        "  wolf_max_size = 10000\n",
        "  wolf_base_energy_decay = 0\n",
        "  wolf_move_energy_cost = 0\n",
        "  wolf_eat_speed = 0.5\n",
        "  wolf_observation_radius = 4\n",
        "  wolf_max_speed = 3\n",
        "\n",
        "  n_grass = 200\n",
        "  n_sheep = 25\n",
        "  n_wolf = 10\n",
        "\n",
        "  QLearning_random = 0.1\n",
        "\n",
        "parameter_dict = parameter()\n",
        "def printpara():\n",
        "  for name, value in inspect.getmembers(parameter_dict):\n",
        "    if not name.startswith('__'):\n",
        "      print(f\"{name}: {value}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## World"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {},
      "outputs": [],
      "source": [
        "class World(mesa.Model):\n",
        "  def __init__(self,parameter,seed=None):\n",
        "    super().__init__(seed=seed)  \n",
        "    self.parameter = parameter\n",
        "    self.width = self.parameter.world_width\n",
        "    self.height = self.parameter.world_height\n",
        "    self.grid = mesa.space.MultiGrid(self.parameter.world_width,self.parameter.world_height,torus=False)\n",
        "    self.history = {}\n",
        "    self.steps = 0\n",
        "    self.non_overlapping_grid = []\n",
        "  def add_agent(self,agent):\n",
        "    x = random.randrange(self.width)\n",
        "    y = random.randrange(self.height)\n",
        "    self.grid.place_agent(agent,(x,y))\n",
        "  def add_non_overlapping_agent(self,agent):\n",
        "    while 1:\n",
        "      x = random.randrange(self.width)\n",
        "      y = random.randrange(self.height)\n",
        "      if (x,y) not in self.non_overlapping_grid:\n",
        "        self.non_overlapping_grid.append((x,y))\n",
        "        break\n",
        "    self.grid.place_agent(agent,(x,y))\n",
        "  def remove_agent(self,agent):\n",
        "    self.agents.remove(agent)\n",
        "  def step(self):\n",
        "    self.agents.shuffle_do(\"step\")\n",
        "  def dynamic_visualization(self,cx_steps=100,interval=0.1,plot_parameter={}):\n",
        "    figure = plt.figure(figsize=(8,6))\n",
        "    plt.rcParams['font.family'] = 'Segoe UI Emoji'\n",
        "    for step in range(cx_steps):\n",
        "      self.step()\n",
        "      plt.clf()\n",
        "      ax = plt.gca()\n",
        "      tmp = {}\n",
        "      # statics on animals\n",
        "      for agent in self.agents:\n",
        "        if agent.agent_class not in tmp:\n",
        "          tmp[agent.agent_class] = {}\n",
        "        tmp[agent.agent_class][agent.unique_id] = {'position':agent.pos,'energy':agent.energy,'action':agent.action,'speed':agent.speed}\n",
        "      self.history[self.steps] = tmp\n",
        "      for agent_class in tmp:\n",
        "        for id in tmp[agent_class]:\n",
        "          plt.text(tmp[agent_class][id]['position'][0],tmp[agent_class][id]['position'][1],plot_parameter[agent_class]['text'],ha='center',va='center',fontsize=tmp[agent_class][id]['energy'])\n",
        "          if np.sum(abs(np.array(tmp[agent_class][id]['speed'])))!=0:\n",
        "            plt.arrow(tmp[agent_class][id]['position'][0],tmp[agent_class][id]['position'][1],tmp[agent_class][id]['action'][0]*0.4,tmp[agent_class][id]['action'][1]*0.4,width=0.1)\n",
        "      ax.set_xlim(0,self.width)\n",
        "      ax.set_ylim(0,self.height)\n",
        "      plt.title(f\"Ecosystem Simulation - Step {step}\")\n",
        "      plt.xlabel(\"X Position\")\n",
        "      plt.ylabel(\"Y Position\")\n",
        "      plt.pause(interval)\n",
        "      clear_output(wait=True)\n",
        "    plt.ioff()\n",
        "    plt.show()\n",
        "    return self.history\n",
        "  \n",
        "  def dynamic_visualization_pygame(self,cx_steps=100,interval=0.1,plot_parameter={}):\n",
        "    for step in range(cx_steps):\n",
        "      self.step()\n",
        "      tmp = {}\n",
        "      # statics on animals\n",
        "      for agent in self.agents:\n",
        "        if agent.agent_class not in tmp:\n",
        "          tmp[agent.agent_class] = {}\n",
        "        tmp[agent.agent_class][agent.unique_id] = {'position':agent.pos,'energy':agent.energy,'action':agent.action,'speed':agent.speed}\n",
        "      self.history[self.steps] = tmp\n",
        "      self.game.checkQuit()\n",
        "      self.game.update(agentsStake=tmp)\n",
        "      self.game.render()\n",
        "    self.game.quit()\n",
        "    return self.history"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Simulation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "x:0,y:0,w:80,h:79\n",
            "x:460,y:921,w:80,h:79\n",
            "[0]:耗费100毫秒\n",
            "[1]:耗费101毫秒\n",
            "[2]:耗费101毫秒\n",
            "[3]:耗费100毫秒\n",
            "[4]:耗费100毫秒\n",
            "[5]:耗费101毫秒\n",
            "[6]:耗费100毫秒\n",
            "[7]:耗费100毫秒\n",
            "[8]:耗费100毫秒\n",
            "[9]:耗费100毫秒\n",
            "[10]:耗费100毫秒\n",
            "[11]:耗费100毫秒\n",
            "[12]:耗费101毫秒\n",
            "[13]:耗费100毫秒\n",
            "[14]:耗费100毫秒\n",
            "[15]:耗费100毫秒\n",
            "[16]:耗费100毫秒\n",
            "[17]:耗费100毫秒\n",
            "[18]:耗费100毫秒\n",
            "[19]:耗费100毫秒\n",
            "[20]:耗费100毫秒\n",
            "[21]:耗费100毫秒\n",
            "[22]:耗费100毫秒\n",
            "[23]:耗费101毫秒\n",
            "[24]:耗费100毫秒\n",
            "[25]:耗费101毫秒\n",
            "[26]:耗费101毫秒\n",
            "[27]:耗费101毫秒\n",
            "[28]:耗费100毫秒\n",
            "[29]:耗费100毫秒\n",
            "[30]:耗费100毫秒\n",
            "[31]:耗费100毫秒\n",
            "[32]:耗费100毫秒\n",
            "[33]:耗费100毫秒\n",
            "[34]:耗费101毫秒\n",
            "[35]:耗费101毫秒\n",
            "[36]:耗费101毫秒\n",
            "[37]:耗费100毫秒\n",
            "[38]:耗费101毫秒\n",
            "[39]:耗费100毫秒\n",
            "[40]:耗费100毫秒\n",
            "[41]:耗费100毫秒\n",
            "[42]:耗费100毫秒\n",
            "[43]:耗费101毫秒\n",
            "[44]:耗费100毫秒\n",
            "[45]:耗费100毫秒\n",
            "[46]:耗费100毫秒\n",
            "[47]:耗费100毫秒\n",
            "[48]:耗费100毫秒\n",
            "[49]:耗费101毫秒\n",
            "[50]:耗费101毫秒\n",
            "[51]:耗费101毫秒\n",
            "[52]:耗费100毫秒\n",
            "[53]:耗费100毫秒\n",
            "[54]:耗费100毫秒\n",
            "[55]:耗费100毫秒\n",
            "[56]:耗费100毫秒\n",
            "[57]:耗费100毫秒\n",
            "[58]:耗费101毫秒\n",
            "[59]:耗费100毫秒\n",
            "[60]:耗费101毫秒\n",
            "[61]:耗费101毫秒\n",
            "[62]:耗费100毫秒\n",
            "[63]:耗费100毫秒\n",
            "[64]:耗费100毫秒\n",
            "[65]:耗费100毫秒\n",
            "[66]:耗费101毫秒\n",
            "[67]:耗费100毫秒\n",
            "[68]:耗费101毫秒\n",
            "[69]:耗费100毫秒\n",
            "[70]:耗费100毫秒\n",
            "[71]:耗费100毫秒\n",
            "[72]:耗费101毫秒\n",
            "[73]:耗费101毫秒\n",
            "[74]:耗费100毫秒\n",
            "[75]:耗费100毫秒\n",
            "[76]:耗费101毫秒\n",
            "[77]:耗费100毫秒\n",
            "[78]:耗费100毫秒\n",
            "[79]:耗费100毫秒\n",
            "[80]:耗费101毫秒\n",
            "[81]:耗费100毫秒\n",
            "[82]:耗费100毫秒\n",
            "[83]:耗费101毫秒\n",
            "[84]:耗费101毫秒\n",
            "[85]:耗费100毫秒\n",
            "[86]:耗费100毫秒\n",
            "[87]:耗费100毫秒\n",
            "[88]:耗费100毫秒\n",
            "[89]:耗费101毫秒\n",
            "[90]:耗费101毫秒\n",
            "[91]:耗费100毫秒\n",
            "[92]:耗费100毫秒\n",
            "[93]:耗费100毫秒\n",
            "[94]:耗费101毫秒\n",
            "[95]:耗费101毫秒\n",
            "[96]:耗费100毫秒\n",
            "[97]:耗费100毫秒\n",
            "[98]:耗费101毫秒\n",
            "[99]:耗费100毫秒\n",
            "[100]:耗费101毫秒\n",
            "[101]:耗费101毫秒\n",
            "[102]:耗费100毫秒\n",
            "[103]:耗费101毫秒\n",
            "[104]:耗费101毫秒\n",
            "[105]:耗费100毫秒\n",
            "[106]:耗费101毫秒\n",
            "[107]:耗费100毫秒\n",
            "[108]:耗费100毫秒\n",
            "[109]:耗费100毫秒\n",
            "[110]:耗费100毫秒\n",
            "[111]:耗费101毫秒\n",
            "[112]:耗费100毫秒\n",
            "[113]:耗费100毫秒\n",
            "[114]:耗费100毫秒\n",
            "[115]:耗费100毫秒\n",
            "[116]:耗费101毫秒\n",
            "[117]:耗费101毫秒\n",
            "[118]:耗费100毫秒\n",
            "[119]:耗费100毫秒\n",
            "[120]:耗费101毫秒\n",
            "[121]:耗费100毫秒\n",
            "[122]:耗费101毫秒\n",
            "[123]:耗费100毫秒\n",
            "[124]:耗费101毫秒\n",
            "[125]:耗费100毫秒\n",
            "[126]:耗费100毫秒\n",
            "[127]:耗费100毫秒\n",
            "[128]:耗费100毫秒\n",
            "[129]:耗费101毫秒\n",
            "[130]:耗费100毫秒\n",
            "[131]:耗费100毫秒\n",
            "[132]:耗费101毫秒\n",
            "[133]:耗费100毫秒\n",
            "[134]:耗费100毫秒\n",
            "[135]:耗费101毫秒\n",
            "[136]:耗费100毫秒\n",
            "[137]:耗费100毫秒\n",
            "[138]:耗费100毫秒\n",
            "[139]:耗费100毫秒\n",
            "[140]:耗费100毫秒\n",
            "[141]:耗费100毫秒\n",
            "[142]:耗费101毫秒\n",
            "[143]:耗费100毫秒\n",
            "[144]:耗费101毫秒\n",
            "[145]:耗费101毫秒\n",
            "[146]:耗费100毫秒\n",
            "[147]:耗费100毫秒\n",
            "[148]:耗费100毫秒\n",
            "[149]:耗费101毫秒\n",
            "[150]:耗费100毫秒\n",
            "[151]:耗费101毫秒\n",
            "[152]:耗费100毫秒\n",
            "[153]:耗费100毫秒\n",
            "[154]:耗费100毫秒\n",
            "[155]:耗费100毫秒\n",
            "[156]:耗费100毫秒\n",
            "[157]:耗费100毫秒\n",
            "[158]:耗费100毫秒\n",
            "[159]:耗费100毫秒\n",
            "[160]:耗费100毫秒\n",
            "[161]:耗费100毫秒\n",
            "[162]:耗费100毫秒\n",
            "[163]:耗费100毫秒\n",
            "[164]:耗费100毫秒\n",
            "[165]:耗费101毫秒\n",
            "[166]:耗费101毫秒\n",
            "[167]:耗费101毫秒\n",
            "[168]:耗费100毫秒\n",
            "[169]:耗费100毫秒\n",
            "[170]:耗费100毫秒\n",
            "[171]:耗费101毫秒\n",
            "[172]:耗费101毫秒\n",
            "[173]:耗费100毫秒\n",
            "[174]:耗费100毫秒\n",
            "[175]:耗费100毫秒\n",
            "[176]:耗费101毫秒\n",
            "[177]:耗费101毫秒\n",
            "[178]:耗费100毫秒\n",
            "[179]:耗费100毫秒\n",
            "[180]:耗费100毫秒\n",
            "[181]:耗费100毫秒\n",
            "[182]:耗费100毫秒\n",
            "[183]:耗费101毫秒\n",
            "[184]:耗费100毫秒\n",
            "[185]:耗费100毫秒\n",
            "[186]:耗费100毫秒\n",
            "[187]:耗费100毫秒\n",
            "[188]:耗费101毫秒\n",
            "[189]:耗费100毫秒\n",
            "[190]:耗费100毫秒\n",
            "[191]:耗费100毫秒\n",
            "[192]:耗费100毫秒\n",
            "[193]:耗费100毫秒\n",
            "[194]:耗费100毫秒\n",
            "[195]:耗费100毫秒\n",
            "[196]:耗费100毫秒\n",
            "[197]:耗费100毫秒\n",
            "[198]:耗费100毫秒\n",
            "[199]:耗费100毫秒\n"
          ]
        },
        {
          "ename": "SystemExit",
          "evalue": "",
          "output_type": "error",
          "traceback": [
            "An exception has occurred, use %tb to see the full traceback.\n",
            "\u001b[31mSystemExit\u001b[39m\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "d:\\cx\\Anaconda\\envs\\CX\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3675: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n",
            "  warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n"
          ]
        }
      ],
      "source": [
        "seed = 0\n",
        "tmp = (parameter_dict.sheep_observation_radius*2+1)\n",
        "field = (tmp,tmp,3)\n",
        "sheep_brain = Brain.Brain_DDPG(observation_radius=parameter_dict.sheep_observation_radius,observation_channel=3,epsilon=parameter_dict.QLearning_random,max_velocity=parameter_dict.sheep_max_speed)\n",
        "sheep_brain.load_weight('../offline/brain/weight_9000.pth')\n",
        "wolf_brain = Brain.Brain_Random()\n",
        "world = World(parameter_dict)\n",
        "c = 0\n",
        "for _ in range(parameter_dict.n_grass):\n",
        "  world.add_agent(Animal.Producer(c,world,'Grass',\n",
        "                                  energy=parameter_dict.grass_born_size,\n",
        "                                  max_energy=parameter_dict.grass_max_size,\n",
        "                                  grow_speed=parameter_dict.grass_grow_speed))\n",
        "  c += 1\n",
        "for _ in range(parameter_dict.n_sheep):\n",
        "  world.add_agent(Animal.Animal(c,world,sheep_brain,'Sheep',prey=['Grass'],predator=['Wolf'],cowoker=['Sheep'],\n",
        "                                energy=parameter_dict.sheep_born_size,\n",
        "                                max_energy=parameter_dict.sheep_max_size,\n",
        "                                eat_speed=parameter_dict.sheep_eat_speed,\n",
        "                                observation_radius=parameter_dict.sheep_observation_radius,\n",
        "                                base_energy_decay=parameter_dict.sheep_base_energy_decay,\n",
        "                                move_energy_cost=parameter_dict.sheep_move_energy_cost))\n",
        "  c += 1\n",
        "for _ in range(parameter_dict.n_wolf):\n",
        "  world.add_agent(Animal.Animal_Test(c,world,'Wolf',prey=['Sheep'],predator=[],cowoker=[],\n",
        "                                     energy=parameter.wolf_born_size,\n",
        "                                     eat_speed=parameter.wolf_eat_speed))\n",
        "  c += 1\n",
        "world.game=Game.GameRender()\n",
        "world.game.FPS=10\n",
        "history = world.dynamic_visualization_pygame(cx_steps=200,interval=0.1,plot_parameter={'Grass':{'text':'🌿'},'Sheep':{'text':'🐑'},'Wolf':{'text':'🐺'}})\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 1000x300 with 2 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "%matplotlib inline\n",
        "history = world.history\n",
        "plt.figure(figsize=(10,3))\n",
        "plt.rcParams['font.family'] = 'Segoe UI Emoji'\n",
        "ax = plt.subplot(1,2,1)\n",
        "for i,k,l in zip(['🌿','🐑','🐺'],['g','b','r'],['Grass','Sheep','Wolf']):\n",
        "  tmp = [len(history[a][l]) for a in history]\n",
        "  ax.plot(tmp,label=i,color=k)\n",
        "ax.legend()\n",
        "ax.set_title('Total number')\n",
        "\n",
        "ax= plt.subplot(1,2,2)\n",
        "tmp = []\n",
        "for i,k,l in zip(['🌿','🐑','🐺'],['g','b','r'],['Grass','Sheep','Wolf']):\n",
        "  tmp = [np.sum([history[a][l][b]['energy'] for b in history[a][l]]) for a in history]\n",
        "  ax.plot(tmp,label=i,color=k)\n",
        "ax.legend()\n",
        "ax.set_title('Total energy')\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.13.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}
